﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace GetComics.Silverlight
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
        }
        /// <summary>
        /// Нажата ли мышка
        /// </summary> 
        private Boolean _isMouseCapture = false;
        private bool _cloneCreated = false;
        private bool _isMouseCaptureByTransRect = false;
        private UIElement _selectedElement;
        private bool _rotateStarted = false;
        /// <summary>
        /// расстояние между мышкой и центром объекта по Х
        /// </summary> 
        double _deltaX;
        /// <summary>
        /// расстояние между мышкой и центром объекта по Y
        /// </summary>
        double _deltaY;


        private void oblako_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Canvas canv = ((Canvas)sender);
            canv.Opacity = 0.5;
            Canvas.SetZIndex(canv, 20);
            TranslateTransform trTrans = this.GetTransform<TranslateTransform>((TransformGroup)canv.RenderTransform);
            _deltaX = e.GetPosition(null).X - trTrans.X;
            _deltaY = e.GetPosition(null).Y - trTrans.Y;
            RotateTransform rtTrans = this.GetTransform<RotateTransform>((TransformGroup)canv.RenderTransform);
            rtTrans.CenterX = canv.Width / 2;
            rtTrans.CenterY = canv.Height / 2;
            canv.CaptureMouse();
            _isMouseCapture = true;
            // событие обработано LayoutRoot_MouseLeftButtonDown не вызывается
            //e.Handled = true;
        }        

        void rectPoint_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isMouseCaptureByTransRect)
            {
                Rectangle rSender = (Rectangle)sender;
                TranslateTransform trTrans = this.GetTransform<TranslateTransform>((TransformGroup)rSender.RenderTransform);
                double y = trTrans.Y;
                //trTrans.X = e.GetPosition(null).X - _deltaX;
                trTrans.Y = e.GetPosition(null).Y - _deltaY;

                RotateTransform rtTrans = this.GetTransform<RotateTransform>((TransformGroup)rSender.RenderTransform);
                rtTrans.CenterX = rSender.Width / 2;
                rtTrans.CenterY = rSender.Height / 2;


                Rectangle r = ((Canvas)rSender.Parent).FindName("transformRect") as Rectangle;
                if (r != null)
                {
                    Canvas.SetTop(r, e.GetPosition((Canvas)rSender.Parent).Y);
                    r.Height += y - trTrans.Y;

                    Canvas.SetTop(img, e.GetPosition((Canvas)rSender.Parent).Y);
                    img.Height += y - trTrans.Y;
                }

            }
        }

        void rectPoint_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Rectangle rSender = (Rectangle)sender;
            rSender.ReleaseMouseCapture();
            _isMouseCaptureByTransRect = false;
        }

        void rectPoint_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Rectangle rSender = (Rectangle)sender;
            TranslateTransform trTrans = this.GetTransform<TranslateTransform>((TransformGroup)rSender.RenderTransform);
            _deltaX = e.GetPosition(null).X - trTrans.X;
            _deltaY = e.GetPosition(null).Y - trTrans.Y;
            rSender.CaptureMouse();
            _isMouseCaptureByTransRect = true;
            e.Handled = true;
        }
        

        private void oblako_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Canvas cSender = (Canvas)sender;
            cSender.ReleaseMouseCapture();
            cSender.Opacity = 1.0;
            Canvas.SetZIndex(cSender, 20);
            _isMouseCapture = false;
        }

        private void txtReplica_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                Canvas cnvCopy = oblako.Clone();
                Ellipse tmpEllipse = null;
                foreach (UIElement ellipse in cnvCopy.Children)
                {
                    if (ellipse is Ellipse) tmpEllipse = ellipse as Ellipse;
                }
                if (tmpEllipse != null)
                    cnvCopy.Children.Remove(tmpEllipse);

                cnvCopy.MouseLeftButtonDown += new MouseButtonEventHandler(oblako_MouseLeftButtonDown);
                cnvCopy.MouseLeftButtonUp += new MouseButtonEventHandler(oblako_MouseLeftButtonUp);
                cnvCopy.MouseMove += new MouseEventHandler(element_MouseMove);
                cnvCopy.RenderTransform = new TransformGroup()
                {
                    Children = {
                            new RotateTransform(),    
                            new TranslateTransform(),
                            new ScaleTransform(),
                        }
                };

                TextBox newReplica = new TextBox();
                newReplica.Text = txtReplica.Text;
                newReplica.FontFamily = txtReplica.FontFamily;
                newReplica.FontSize = txtReplica.FontSize;
                newReplica.FontWeight = newReplica.FontWeight;
                newReplica.GotFocus += new RoutedEventHandler(txtReplica_GotFocus);
                cnvCopy.MouseMove += new MouseEventHandler(element_MouseMove);
                Canvas.SetLeft(newReplica, Canvas.GetLeft(txtReplica));
                Canvas.SetTop(newReplica, Canvas.GetTop(txtReplica));
                cnvCopy.Children.Add(newReplica);
                cnvCopy.KeyDown += oblako_KeyDown;

                LayoutRoot.Children.Add(cnvCopy);

                txtReplica.Text = "Type your text hear";
            }
        }

        private void txtReplica_GotFocus(object sender, RoutedEventArgs e)
        {
            TextBox txtSender = (TextBox)sender;
            txtSender.Select(0, txtSender.Text.Length);
        }

        private void btnMirror_Click(object sender, RoutedEventArgs e)
        {

            SuperCanvas sc = new SuperCanvas();
            
            Rectangle rectPoint1 = CreareRectStub();
            ResizableCanvas rc = new ResizableCanvas();
            rc.ElementToResize = rectPoint1;
            rc.Children.Add(rectPoint1);
            rc.Tag = new Dragger(true, true);
            rc.RenderTransform = new TransformGroup { Children = new TransformCollection { new TranslateTransform() } };

            sc.AddDragable(rc);
            LayoutRoot.Children.Add(sc);
        }

        private static Rectangle CreareRectStub()
        {
            Rectangle rectPoint;
            rectPoint = new Rectangle();
            rectPoint.Height = 30;
            rectPoint.Width = 30;
            rectPoint.Fill = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
            rectPoint.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            rectPoint.RenderTransform = new TransformGroup { Children = new TransformCollection { new TranslateTransform() } };
            return rectPoint;
        }

        private T GetTransform<T>(TransformGroup trGroup) where T : Transform
        {
            return (T)(from trans in trGroup.Children
                       where trans.GetType() == typeof(T)
                       select trans).First();
        }

        private void oblako_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.PageDown)
            {
                Canvas oblakoCanvas = sender as Canvas;
                RotateTransform rtTrans = this.GetTransform<RotateTransform>((TransformGroup)oblakoCanvas.RenderTransform);
                rtTrans.CenterX = oblakoCanvas.Width / 2;
                rtTrans.CenterY = oblakoCanvas.Height / 2;
                rtTrans.Angle += 10;
            }
            if (e.Key == Key.PageUp)
            {
                Canvas oblakoCanvas = sender as Canvas;
                RotateTransform rtTrans = this.GetTransform<RotateTransform>((TransformGroup)oblakoCanvas.RenderTransform);
                rtTrans.CenterX = oblakoCanvas.Width / 2;
                rtTrans.CenterY = oblakoCanvas.Height / 2;

                rtTrans.Angle -= 10;
            }
        }

        private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //Rectangle r = ((Canvas)sender).FindName("transformRect") as Rectangle;
            //if (r != null)
            //{
            //    ((Canvas)r.Parent).Children.Remove(r);
            //}
        }

        private Point GetCanvasCenter(Canvas canvas)
        {
            return new Point(canvas.Width / 2, canvas.Height / 2);
        }

        private void element_MouseMove(object sender, MouseEventArgs e)
        {
            Canvas canv = (Canvas)sender;

            if (_isMouseCapture && !_isMouseCaptureByTransRect)
            {
                TranslateTransform trTrans = this.GetTransform<TranslateTransform>((TransformGroup)canv.RenderTransform);
                trTrans.X = e.GetPosition(null).X - _deltaX;
                trTrans.Y = e.GetPosition(null).Y - _deltaY;
            }
            if (_selectedElement != canv)
            {
                if (_selectedElement is Canvas)
                {
                    Ellipse tmpEllipse = null;
                    foreach (UIElement tellipse in (_selectedElement as Canvas).Children)
                    {
                        if (tellipse is Ellipse) tmpEllipse = tellipse as Ellipse;
                    }

                    if (tmpEllipse != null)
                        (_selectedElement as Canvas).Children.Remove(tmpEllipse);
                }
                Ellipse ellipse = new Ellipse();
                ellipse.Height = 20;
                ellipse.Width = 20;
                ellipse.MouseMove += new MouseEventHandler(rotate_MouseMove);
                ellipse.MouseLeftButtonUp += new MouseButtonEventHandler(rotate_MouseLeftButtonUp);
                ellipse.MouseLeftButtonDown += new MouseButtonEventHandler(rotate_MouseLeftButtonDown);
                canv.Children.Add(ellipse);
                Canvas.SetTop(ellipse, canv.Height / 2 + 100);
                Canvas.SetLeft(ellipse, canv.Width / 2 - 10);
                ellipse.Stroke = new SolidColorBrush(Colors.Black);
                ellipse.StrokeThickness = 3;
                ellipse.Fill = new SolidColorBrush(Colors.Red);

                _selectedElement = canv;
            }
        }

        private void rotate_MouseMove(object sender, MouseEventArgs e)
        {
            if (_rotateStarted)
            {
                Canvas oblakoCanvas = (sender as Ellipse).Parent as Canvas;
                RotateTransform rtTrans = this.GetTransform<RotateTransform>((TransformGroup)oblakoCanvas.RenderTransform);
                TranslateTransform trTrans = this.GetTransform<TranslateTransform>((TransformGroup)oblakoCanvas.RenderTransform);
                Point center = new Point(oblakoCanvas.Width / 2, oblakoCanvas.Height / 2);
                rtTrans.CenterX = oblakoCanvas.Width / 2;
                rtTrans.CenterY = oblakoCanvas.Height / 2;

                // Вычисляем разницы между центром облака и положением красной хрени
                double deltaX = e.GetPosition(oblakoCanvas.Parent as Canvas).X - Canvas.GetLeft(oblakoCanvas) - (oblakoCanvas.Width / 2) - trTrans.X;
                double deltaY = e.GetPosition(oblakoCanvas.Parent as Canvas).Y - Canvas.GetTop(oblakoCanvas) - (oblakoCanvas.Height / 2) - trTrans.Y;

                // Вычисляем угол поворота
                rtTrans.Angle = -180 * Math.Atan(deltaX / deltaY) / Math.PI;//(deltaY/Math.Sqrt(deltaX*deltaX+(deltaY*deltaY)));
                if (deltaY < 0) rtTrans.Angle += 180;
            }
        }
        private void rotate_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _rotateStarted = true;
            e.Handled = true;
        }

        private void rotate_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _rotateStarted = false;
            e.Handled = true;
        }

    }
}
